---@class Battle.ReportMgr
local ReportMgr = Battle.CreateClass("ReportMgr")
Battle.ReportMgr = ReportMgr
ReportMgr.isPrint = true
ReportMgr.isTrace = false
ReportMgr.isConsole = false
local BUFF_COLOR = "55BB55"
local DAMAGE_COLOR = "FF5555"
local ATTR_COLOR = "5599FF"
local this = ReportMgr
local LOG_PATH = ""
function ReportMgr.OnCreate()

    this.isWindowEditor = Util.IsRuntimePlatform(7)
    if this.isWindowEditor then
        this.Register()
        if this.isPrint then
            LOG_PATH = "Logs/"..this.GetFileName()..".txt"
            Util.WriteToFile(LOG_PATH,"",false)
        end
    end
end
function ReportMgr.OnDestroy()
end

function ReportMgr.Register()
    local system = Battle.GlobalEventSystem
    system.Register(Battle.Event.ActorInitializeBefore,this.ActorInitializeBefore)
    system.Register(Battle.Event.ActorCreate,this.ActorCreate)
    system.Register(Battle.Event.ActorDead,this.ActorDead)
    system.Register(Battle.Event.BuffCreate,this.BuffCreate)
    system.Register(Battle.Event.BuffActive,this.BuffActive)
    system.Register(Battle.Event.BuffLayerChange,this.BuffLayerChange)
    system.Register(Battle.Event.BuffDestroy,this.BuffDestroy)
    system.Register(Battle.Event.SkillStart,this.SkillStart)
    --system.Register(Battle.Event.SkillHitBefore,this.HitBefore)
    system.Register(Battle.Event.ActorHitBeforeFinish,this.HitBefore)
    system.Register(Battle.Event.ActorEffectStateChange,this.ActorEffectStateChange)
    system.Register(Battle.Event.ActorAttributeChange,this.ActorAttributeChange)

end

function ReportMgr.GetTimeStr()
    return os.date("%H:%M:%S   ",os.time())
end
function ReportMgr.GetFileName()
    return os.date("log%y-%m-%d %H %M %S",os.time())
end
---@param args BattleEvent
function ReportMgr.ActorInitializeBefore(args)
    local entity = args.sender
    local str ="[英雄创建]"..entity:ToString()
    this.Print(str)
end
---@param args BattleEvent
function ReportMgr.ActorCreate(args)
    local entity = args.sender
    this.PrintAttribute(entity, nil,entity.attrSystem.attrList)
end
---@param args BattleEvent
function ReportMgr.ActorDead(args)
    local entity = args.dead
    local str = "[英雄死亡]"..entity:ToString()
    this.Print(str)
end
---@param args BattleEvent
function ReportMgr.BuffCreate(args)
    local buff = args.buff
    local str = "[Buff创建]"..buff:ToString()
    this.Print(str,BUFF_COLOR)
end
---@param args BattleEvent
function ReportMgr.BuffActive(args)
    local buff = args.buff
    local str = "[Buff激活]"..buff:ToString()
    this.Print(str,BUFF_COLOR)
end
---@param args BattleEvent
function ReportMgr.BuffLayerChange(args)
    local buff = args.buff
    local str = "[Buff刷新]"..buff:ToString()
    this.Print(str,BUFF_COLOR)
end
---@param args BattleEvent
function ReportMgr.BuffDestroy(args)
    local buff = args.buff
    local str = "[Buff销毁]"..buff:ToString()
    this.Print(str,BUFF_COLOR)
end
---@param actor Battle.Entity
function ReportMgr.GetHeroShortStr(actor)
    local camp = actor.camp == Battle.CampType.Blue and "我方" or "敌方"
    return "英雄: "..actor.modelId.."("..camp..") "
end
---@param args SkillArgs
function ReportMgr.SkillStart(args)
    local skill = args.skill
    local str = "[技能释放] "..this.GetHeroShortStr(skill.actor) .." skillId:"..skill.skillId
    this.Print(str)
end
---@param args Battle.HitArgs
function ReportMgr.HitBefore(args)
    this.PrintDamageData("[命中]",args.damageData)
end
function ReportMgr.PrintDamageData(prefixTip,data)
    ---@type Battle.Entity
    local attacker = data.attacker
    ---@type Battle.Entity
    local target =  data.target
    local damage =  data.damage
    local isCrit =  data.isCrit
    local sourceType =  data.sourceType or 0
    local sourceId =  data.sourceId or 0
    local str = string.format(prefixTip.."%s ,命中目标%s ,造成伤害：%0.1f,是否暴击：%s",
            this.GetHeroShortStr(attacker),this.GetHeroShortStr(target),damage,tostring(isCrit))
    local sourceName = ""
    if sourceType == Battle.SourceType.Skill then
        sourceName = " ,来源技能："
    elseif sourceType == Battle.SourceType.Bullet then
        sourceName = " ,来源子弹："
    elseif sourceType == Battle.SourceType.Buffer then
        sourceName = " ,来源buff: "
    end

    this.Print(str,DAMAGE_COLOR)
end
---@param args BattleEvent
function ReportMgr.ActorAttributeChange(args)
    local entity = args.sender
    local old = args.oldAttrList
    local new  = args.curAttrList
    this.PrintAttribute(entity, old,new)
end
---@param args BattleEvent
function ReportMgr.ActorEffectStateChange(args)
    local sender = args.sender
    local stateId = args.stateId
    local isAdd = args.isAdd
    local addStr = isAdd and " 添加" or " 移除"
    local str = "[状态变更]"..this.GetHeroShortStr(sender)..addStr.." 状态："..stateId.."("..Battle.FighterStateEnum.GetStateName(stateId)..")"
    this.Print(str)
end

function ReportMgr.PrintAttribute(entity,old,new)
    local str = "[属性变更]"..this.GetHeroShortStr(entity)
    if old then
        local str1 = str.." (旧) "
        for k,v in pairs(old) do
            if v ~= 0 then
                str1 = str1..k.."("..Battle.AttributeType.GetName(k)..")="..v.." "
            end
        end
        this.Print(str1)
    end
    if new then
        local str1 = str.." (新) "
        if old then
            for k,v in pairs(new) do
                if v ~= old[k] then
                    str1 = str1..k.."("..Battle.AttributeType.GetName(k)..")="..v.." "
                end
            end
            this.Print(str1,ATTR_COLOR)
        else
            for k,v in pairs(new) do
                if v ~= 0 then
                    str1 = str1..k.."("..Battle.AttributeType.GetName(k)..")="..v.." "
                end
            end
            this.Print(str1)
        end

    end
end

function ReportMgr.Print(str,color)
    if not this.isPrint then
        return
    end
    local str = this.GetTimeStr()..tostring(str)
    if this.isTrace then
        str = debug.traceback(str)
    end
    Util.WriteToFile(LOG_PATH,str,true)
    if this.isConsole then
        if color then
            log(string.format("<color=#%s>%s</color>",color,str))
        else
            log(str)
        end
    end
end
